#ifndef USER_PLUGIN_CLASS
#define USER_PLUGIN_CLASS

#include "pland.hpp"
using pland::SharedDQueue;

/*! \brief User Plugins. This is the base class for all plugin classes
 * All plugin classes must inherit from this method. This class is pure virtual,
 * only plugins implement these methods.
 *
 * Since libld can only hook on to C functions two functions C functions
 * Core_GetInstance and Core_KillInstance need to be implemented in the
 * plugin library for proper function of the plugins.
 *
 * Compiling and Linking:
 * Code needs to be compiled with "-fPIC" and linked with "-shared -Wl,-soname,library_name.so"
 *
 * For more information examine plugin/dummy.cpp
 * */
class UserC_Plugin
{
public:
    /*!
     * This function gets called when the thread is created.
     * It should be implemented as an infinite loop
     * */
    virtual void start() = 0;

    /*!
     * This function gets called to notify the plugin thread
     * that it should stop.
     */
    virtual void stop() = 0;

    /*!
     * This function loads the working queues for the plugin.
     * Plugins are responsible for passing all data they find appropriate from front queue
     * to the back queue.
     * \param front front queue may be NULL for a gather plugin.
     * \param back back queue may be NULL for a store plugin.
     * */
    virtual void load_queues(SharedDQueue front ,SharedDQueue back) = 0;

    /*!
     * This function sets the plugin ID.
     * \param id ID for the pluggin.
     * */
    virtual void setId(int id) = 0;
};

extern "C"
{
    /*!
     * This function should return  UserC_Plugin instance.
     * This C function must be wrapped in extern "C" so it can be hooked on to by libld.
     * \return an instance of the plugin.
     * */
    UserC_Plugin* Core_GetInstance();

    /*!
     * Since the Plugin is not implemented in the core code, the destructor is not linked in.
     * This function is responsible for deleteing the Plugin instance.
     * This C function must be wrapped in extern "C" so it can be hooked on to by libld.
     * \param a plugin to be destroyed.
     * */
    void Core_KillInstance(UserC_Plugin* a);
}


#endif /*plugin.hpp*/
